package com.xxwy.dependency.lookup;

import com.xxwy.dependency.Super;
import com.xxwy.dependency.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Map;

/**
 * 依赖查找
 * parent="user" 父类的填充
 * primary="true" 优先级是最高的
 * @author wy
 * @date 2020/4/20 9:47
 */
public class Demo {

  public static void main(String[] args) {
    BeanFactory context = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");

    System.out.println("根据Bean名称查找");
    byName(context);
//
//    System.out.println("\n根据Bean类型查找");
//    byType(context, User.class);
//
//    System.out.println("\n根据注解查找");
//    byAnnotation(context, Super.class);

  }

  private static void byAnnotation(BeanFactory beanFactory, Class<Super> superClass) {
    //lookupAnnotationSingle(beanFactory);
    lookupAnnotationCollect(beanFactory,superClass);
  }

  private static void lookupAnnotationSingle(BeanFactory beanFactory) {
  }

  private static void lookupAnnotationCollect(BeanFactory beanFactory, Class<Super> superClass) {
    if(beanFactory instanceof ListableBeanFactory){
      ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
      Map<String, Object> beans = listableBeanFactory.getBeansWithAnnotation(superClass);
      System.out.println("集合：");
      beans.forEach((k,v)->{
        System.out.print(k + " ");
        System.out.println(v);
      });
    }
  }

  private static void byType(BeanFactory context, Class<User> userClass) {
    // 单个Bean对象, primary="true"
    lookupSingle(context,userClass);

    // 查找集合对象
    lookupCollect(context,userClass);
  }

  private static void lookupCollect(BeanFactory beanFactory, Class<User> userClass) {
    if(beanFactory instanceof ListableBeanFactory){
      ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
      Map<String, User> beansOfType = listableBeanFactory.getBeansOfType(userClass);
      System.out.println("集合：");
      beansOfType.forEach((k,v)->{
        System.out.print(k + " ");
        System.out.println(v);
      });
    }

  }

  private static void lookupSingle(BeanFactory beanFactory, Class<User> userClass) {
    User user = beanFactory.getBean(userClass);
    System.out.println("单个Bean对象" + user);
  }

  private static void byName(BeanFactory beanFactory) {
    // 实时查找
    lookupRealTime(beanFactory);

    //延时查找
    lookupLazy(beanFactory);
  }

  private static void lookupRealTime(BeanFactory context){
    User user = context.getBean("user", User.class);
    System.out.println("实时查找" + user);
  }

  private static void lookupLazy(BeanFactory context) {
    //org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean.TargetBeanObjectFactory
    ObjectFactory<User> objectFactory = (ObjectFactory<User>) context.getBean("objectFactory");
    User user = objectFactory.getObject();
    System.out.println("延时查找：" + user);

  }


}
